package jadeCW.behaviour;

import jade.core.behaviours.CyclicBehaviour;
import jade.lang.acl.ACLMessage;
import jade.lang.acl.MessageTemplate;
import jadeCW.HospitalAgent;
import jadeCW.output.Printer;

/**
 * Allocate Appointment behaviour class
 * 
 * @author br08, dac108, dv08
 */
public class AllocateAppointment extends CyclicBehaviour {
	/**
	 * Generated serialisation ID
	 */
	private static final long serialVersionUID = -3380258792248585224L;

	@Override
	public void action() {
		// must be run on a hospital
		if (!(myAgent instanceof HospitalAgent)) {
			return;
		}

		HospitalAgent hospital = (HospitalAgent) myAgent;

		// create the request message template
		MessageTemplate template = MessageTemplate.and(MessageTemplate
				.MatchPerformative(ACLMessage.REQUEST), MessageTemplate
				.MatchConversationId(RequestAppointment.TYPE));

		// receive the message
		ACLMessage message = hospital.receive(template);

		// if no message is received
		if (message == null) {
			block();
			return;
		}

		Printer.printAllocateReceive(hospital, message.getSender());
		
		// create the reply
		ACLMessage reply = message.createReply();

		// for each possible appointment
		for (int appointment : hospital.getAppointments().keySet()) {
			// if the appointment is allocated, ignore it
			if (hospital.getAppointments().get(appointment) != null) {
				continue;
			}

			// set up and send the propose message with the appointment number
			reply.setPerformative(ACLMessage.PROPOSE);
			reply.setContent(String.valueOf(appointment));
			
			Printer.printAllocateSendPropose(hospital, message.getSender(), appointment);
			
			hospital.send(reply);

			// record the sender as having the given appointment
			hospital.setAppointment(appointment, message.getSender());

			return;
		}

		Printer.printAllocateSendRefuse(hospital, message.getSender());
		
		// send a refuse message (no available appointments)
		reply.setPerformative(ACLMessage.REFUSE);
		reply.setContent(null);
		hospital.send(reply);
	}
}
